/**
 * This file is part of Adaptools.
 * 
 * Adaptools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Adaptools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 * along with Adaptools.  If not, see http://www.gnu.org/licenses/. 
 */
package org.adaptools.base;

import java.util.Collection;
import java.util.Stack;

/**
 * Interface to Mechanism
 * 
 * @author Denys G. Santos (gsdenys@gmail.com)
 * @since 3.0.0
 */
public interface Mechanism extends Copyable<Mechanism>{
	
	/**
	 * Get the id of mechanism. This Id need be generated by Repository module.
	 * 
	 * @return the id of mechanism
	 */
	public String getId();
	
	/**
	 * overwrite the id of mechanism.
	 */
	public void setId(String UUID);
		
	/**
	 * Add a rule to the mechanism
	 * 
	 * @param rule - the rule to be added
	 */
	public void add(Rule rule);
	
	/**
	 * Add a collection of rules
	 * 
	 * @param rules - the collection to be added
	 */
	public void add(Collection<Rule> rules);
	
	/**
	 * Search the rule in the mechanism. This search is based in the contained 
	 * values in the parameter {@link Rule}. 
	 * 
	 * In this search the value of {@link Rule} attributes can assume distinct functions
	 * like follow description:
	 * <ul>
	 * 		<li><b>Normal Attribute:</b> Every time when the attribute contains the value
	 * used normally in the execution it will be used to be compared with the others 
	 * rules attribute in the Mechanism - Every time it is AND</li>
	 * 	    <li><b>Create Variable:</b> When one of attributes of {@link Rule} is started
	 * with <b>?</b> symbol is created a new variable is created. i.e. when is used the 
	 * <b>?p</b> a variable p is created with the value of <b>p</b> assumes in the rule</li>
	 * 		<li><b>Null Symbol:</b> If any of the {@link Rule} attributes is null then
	 * its is ignored in the search.</li>
	 * </ul>
	 *   
	 * @param rule - the rule searched
	 * @return a collection of Rules found.
	 */
	public Collection<Rule> search(Rule rule);
	
	/**
	 * Remove the {@link Rule} from {@link Mechanism}
	 * 
	 * @param rule - the rule to be removed
	 */
	public void remove(Rule rule);
	
	/**
	 * remove the {@link Collection} of {@link Rule} from the {@link Mechanism}
	 * 
	 * @param rules - the {@link Collection} of {@link Rule} to be removed
	 */
	public void remove(Collection<Rule> rules);
	
	/**
	 * Get the name of initial state
	 * 
	 * @return the name of initial state
	 */
	public String getInitialStateName();
	
	/**
	 * get the output ({@link Queue}) object
	 * 	
	 * @return the output object
	 */
	public Queue getOutput();
	
	/**
	 * Set the output ({@link Queue}) object
	 * 
	 * @param output - the object to be set
	 */
	public void setOutput(Queue output);
	
	/**
	 * Get the {@link Queue} of mechanism
	 * 
	 * @return the Queue
	 */
	public Queue getQueue();
	
	/**
	 * Set the {@link Queue} to {@link Mechanism} 
	 * 
	 * @param queue - the queue to be set
	 */
	public void setQueue(Queue queue);
	
	/**
	 * get the transducer ({@link Queue}) object
	 * 	
	 * @return the transducer object
	 */
	public Queue getTransducer();
	
	/**
	 * Set the transducer ({@link Queue}) object
	 * 
	 * @param transducer - the object to be set
	 */
	public void setTransducer(Queue output);
	
	/**
	 * Get {@link Rule} {@link Collection}  
	 * 
	 * @param queue - the queue to be set
	 */
	public Collection<Rule> getRuleCollection();
	
	/**
	 * Get the Adaptive {@link Rule} that has named as parameter
	 * 
	 * @param adaptativeRuleName
	 * @return {@link Collection} of {@link Rule}
	 */
	public Collection<Rule> getAdaptiveRules(String adaptativeRuleName);
	
	/**
	 * Get All Adaptive {@link Rule}
	 * 
	 * @return {@link Collection} of {@link Rule}
	 */
	public Collection<Rule> getAdaptiveRules();
	
	/**
	 * Get the rule in execution
	 * 
	 * @return {@link String}
	 */
	public String getRuleState();
	
	/**
	 * Set Rule in execution
	 * 
	 * @param ruleState
	 */
	public void setRuleState(String ruleState);
	
	/**
	 * Set the Machine State
	 * 
	 * @param state
	 */
	public void setMachineState(MechanismState state);
	
	/**
	 * Get Machine State
	 * 
	 * @return {@link MechanismState}
	 */
	public MechanismState getMachineState();
	
	/**
	 * verify if it is a final state
	 * 
	 * @return {@link Boolean}
	 */
	public Boolean isFinalState();
	
	/**
	 * set final state
	 * 
	 * @param finalState
	 */
	public void setFinalState(Boolean finalState);
	
	/**
	 * get {@link Stack}
	 * 
	 * @return {@link Stack} of {@link String}
	 */
	public Stack<String> getStack();
	
	/**
	 * set {@link Stack}
	 * 
	 * @param stack
	 */
	public void setStack(Stack<String> stack);
}